/**
 * 20081226 1459: Grady.Kao, delete method transCentury2TWDate() and transTW2CenturyDate().<br>
 * 20081225 1534: Grady.Kao, 將 increaseDate() 刪除, 由 java.util.Calendar.add() 來取代<br>
 * 20080205 0937: Grady.Kao, 使用常數傳入, 來取得 Logger<br>
 */

package com.e885.util.date;

import java.util.Calendar;
import java.util.Date;

import static com.e885.constant.util.DirectionConstant.*;
import static com.e885.constant.util.OrderConstant.*;

import com.e885.constant.util.DirectionConstant;
import com.e885.util.array.ArraysUtil;
import com.e885.util.numeric.RandomUtil;

/**
 * 有關 Date Util
 * 
 * @author Grady.Kao
 * @version 1.0
 * @company E885 Group
 * @copyright Copyright (c) 2000-2008
 */
public class DateUtil
{
	/**
	 * 取得一個月的天數<br>
	 * 陽歷有潤年, 每四年潤一次(4的倍數), 所以潤年可以到達 29 天
	 * 
	 * @param year 年份
	 * @param month　月份
	 * @return
	 */
	public static int fetchDaysInMonth( int year, int month )
	{
		if( year < 1900 )
			throw new IllegalArgumentException( "the value of the year less than 1900" );

		if( month < 0 )
			throw new IllegalArgumentException( "the value of the month less than 1" );

		if( month > 11 )
			throw new IllegalArgumentException( "the value of the month great than 12" );

		// 單月
		if( month == 0 || month == 2 || month == 4 || month == 6 || month == 7 || month == 9 || month == 11 )
			return 31;
		else
		{
			// 二月
			if( month == 1 )
			{
				// 每四年潤一次
				if( year % 4 == 0 )
					return 29;
				else
					return 28;
			}
			else
				return 30;
		}
	}

	/**
	 * 亂數取得日期<br>
	 * 但不會超過系統的時間
	 * 
	 * @param startYear 起始年
	 * @return 亂數日期
	 */
	public static Date fetchRandomDate( int startYear )
	{
		Calendar calendar = Calendar.getInstance();

		int tempYear = fetchRandomYear( startYear );
		int tempMonth = fetchRandomMonth( tempYear );

		calendar.set( Calendar.YEAR, tempYear );
		calendar.set( Calendar.MONTH, tempMonth );
		calendar.set( Calendar.DAY_OF_MONTH, fetchRandomDay( tempYear, tempMonth ) );

		return calendar.getTime();
	}

	/**
	 * 亂數抓取日<br>
	 * 但不超過系統時間
	 * 
	 * @param year
	 * @return 亂數取得日
	 */
	public static int fetchRandomDay( int year, int month )
	{
		if( year < 1900 )
			throw new IllegalArgumentException( "the value of the year less than 1900" );

		if( month < 0 )
			throw new IllegalArgumentException( "the value of the yeamonthr less than 0" );

		if( month > 11 )
			throw new IllegalArgumentException( "the value of the month great than 11" );

		Calendar calendar = Calendar.getInstance();

		int randomRangeValue = 0;

		if( year > calendar.get( Calendar.YEAR ) || ( year == calendar.get( Calendar.YEAR ) && month >= calendar.get( Calendar.MONTH ) ) )
			randomRangeValue = calendar.get( Calendar.DAY_OF_MONTH );
		else
			randomRangeValue = fetchDaysInMonth( year, month );

		return RandomUtil.randomByInteger( randomRangeValue ) + 1;
	}

	/**
	 * 亂數抓取月<br>
	 * 但不超過系統時間
	 * 
	 * @param year
	 * @return 亂數取得月
	 */
	public static int fetchRandomMonth( int year )
	{
		if( year < 1900 )
			throw new IllegalArgumentException( "the value of the year less than 1900" );

		Calendar calendar = Calendar.getInstance();

		int currentYear = calendar.get( Calendar.YEAR );
		int currentMonth = calendar.get( Calendar.MONTH );

		if( year >= currentYear )
			return RandomUtil.randomByInteger( currentMonth + 1 );

		return RandomUtil.randomByInteger( 12 );
	}

	/**
	 * 亂數抓取年<br>
	 * 但不超過系統年
	 * 
	 * @param startYear 起始年
	 * @return 亂數取得年
	 */
	public static int fetchRandomYear( int startYear )
	{
		if( startYear < 1900 )
			throw new IllegalArgumentException( "the value of the startYear less than 1900" );

		Calendar calendar = Calendar.getInstance();

		int currentYear = calendar.get( Calendar.YEAR );

		if( startYear >= currentYear )
			return currentYear;

		return RandomUtil.randomByInteger( currentYear - startYear + 1 ) + startYear;
	}

	/**
	 * @see com.e885.util.date.DateUtil#fetchYear(int, int, String, int)
	 */
	public static int[] fetchYear( Date date, int amount, String order, int direction )
	{
		Calendar calendar = Calendar.getInstance();

		calendar.setTime( date );

		return fetchYear( calendar.get( Calendar.YEAR ), amount, order, direction );
	}

	/**
	 * 取得年的陣列, 如傳入的年份為 2008 年, 要取五個(往前計算), 由大至小, 那麼結果為 2008, 2007, 2006, 2005, 2004
	 * 
	 * @param year 要計算的起始年份
	 * @param amount 取得數量
	 * @param order 取得年份的排序, 請使用 DateUtil.ASCEND or DateUtil.DESCEND
	 * @param direction 往前或往後計算, front: 往前計算, 年份愈來愈小
	 * @return 年份的陣列
	 */
	public static int[] fetchYear( int year, int amount, String order, int direction )
	{
		if( year < 1900 )
			throw new IllegalArgumentException( "year less than 1900" );

		if( amount < 1 )
			throw new IllegalArgumentException( "amount less than 1" );

		if( order == null )
			throw new IllegalArgumentException( "order is null" );

		if( !( order.equals( ASCEND ) || order.equals( DESCEND ) ) )
			throw new IllegalArgumentException( "the value of the order is error" );

		if( !( direction == FRONT || direction == BACK ) )
			throw new IllegalArgumentException( "the value of the direction is error" );

		if( ( year - ( amount - 1 ) ) < 1900 )
			throw new IllegalArgumentException( "return value less than 1900" );

		int[] years = new int[ amount ];

		years[ 0 ] = year;

		for( int i = 1; i < amount; i++ )
		{
			if( direction == DirectionConstant.FRONT )
				years[ i ] = --year;
			else
				years[ i ] = ++year;
		}

		ArraysUtil.sort( years, order );

		return years;
	}

	/**
	 * 當傳進去的日期時間, 超過系統時間, 將會回傳系統時間, 如果沒有超過, 則回傳回來的日期時間
	 * 
	 * @param source 傳進去的日期時間
	 * @return a Date
	 */
	public static Date fetchLessThanOrEqualCurrentDate( Date date )
	{
		Date currentDate = new Date();

		if( date == null )
			throw new IllegalArgumentException( "dae is null" );

		if( date.after( currentDate ) )
			return currentDate;

		return date;
	}

	/**
	 * 取得兩個日期相差的天數
	 * 
	 * @param startDate
	 * @param endDate
	 * @return 相差天數, 如果回傳 -1, 那麼結束日期是小於開始日期
	 */
	public static int minusDate( Date startDate, Date endDate )
	{
		if( startDate == null )
			throw new IllegalArgumentException( "startDate is null" );

		if( endDate == null )
			throw new IllegalArgumentException( "endDate is null" );

		long tempLong = ( long )24 * 60 * 60 * 1000;

		long startTime = startDate.getTime();
		long endTime = endDate.getTime();

		long minusTime = endTime - startTime;

		if( minusTime < 0 )
			return -1;

		return ( int )( minusTime / tempLong );
	}
}
